package com.starleague.battletech.hexagonal;

import java.util.Random;

import com.starleague.hexagonal.HexException;
import com.starleague.hexagonal.IHexCoordinate;
import com.starleague.hexagonal.ImmutableHexCoordinate;

public class BattletechHexGridGenerator<HEX_GRID extends IBattletechHexGrid<HEX>, HEX extends IBattletechHex<HEX_GRID>>
{
    private final Random random = new Random(33);
    private final IBattletechHexGridFactory<HEX_GRID, HEX> battletechHexGridFactory;

    public BattletechHexGridGenerator(IBattletechHexGridFactory<HEX_GRID, HEX> battletechHexGridFactory)
    {
        this.battletechHexGridFactory = battletechHexGridFactory;
    }

    public HEX_GRID generateRandomHexGrid(int numHexesX,
                                          int numHexesY) throws HexException
    {
        HEX_GRID hexGrid = this.battletechHexGridFactory.createHexGrid(0, 0, numHexesX, numHexesY);

        for (int gridX = 0; gridX < hexGrid.getNumHexesX(); ++gridX)
            for (int gridY = 0; gridY < hexGrid.getNumHexesY(); ++gridY)
                generateRandomHex(hexGrid, new ImmutableHexCoordinate(gridX, gridY));

        return hexGrid;
    }

    public HEX generateRandomHex(HEX_GRID hexGrid,
                                 IHexCoordinate hexCoordinate) throws HexException
    {
        HEX hex = this.battletechHexGridFactory.createHex(hexGrid, hexCoordinate, this.random.nextInt(7) - 2);

        IBattletechHexTerrain<HEX> hexBaseTerrain = generateRandomBaseHexTerrain(hex);

        generateRandomHexTerrainFeatures(hex, hexBaseTerrain);

        return hex;
    }

    private IBattletechHexTerrain<HEX> generateRandomBaseHexTerrain(HEX hex) throws HexException
    {
        return this.random.nextBoolean()
                ? this.battletechHexGridFactory.createHexTerrain(hex, BattletechHexTerrainType.PLAINS, 0)
                : this.battletechHexGridFactory.createHexTerrain(hex,
                                                                 BattletechHexTerrainType.WATER,
                                                                 this.random.nextInt(3));
    }

    private void generateRandomHexTerrainFeatures(HEX hex,
                                                  IBattletechHexTerrain<HEX> hexBaseTerrain) throws HexException
    {
        switch (hexBaseTerrain.getHexTerrainType())
        {
            case PLAINS:
            {
                switch (this.random.nextInt(10))
                {
                    case 0:
                        this.battletechHexGridFactory.createHexTerrain(hex,
                                                                       BattletechHexTerrainType.WOODS,
                                                                       this.random.nextInt(2));
                        break;

                    case 1:
                        this.battletechHexGridFactory.createHexTerrain(hex,
                                                                       BattletechHexTerrainType.ROUGH,
                                                                       this.random.nextInt(2));
                }
                break;
            }

            case ROUGH:
            case WATER:
            case WOODS:
        }
    }
}
